package com.putao.base;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.putao.constants.Constants;
import com.putao.error.BusinessException;
import com.putao.result.JsonResult;
import com.putao.utils.AssertUtil;
import com.putao.utils.HumpUtil;
import com.putao.utils.ReflexUtil;
import com.putao.utils.ThreadLocalUtil;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Field;
import java.util.List;

import static com.putao.constants.Constants.REFLECT_CHECK_EMPTY_COLUMN_ARRAY_EMPTY;


/**
 * @author fuhehuang
 * @email 2628279194@qq.com
 */
public interface BaseService<T> extends IService<T> {

    /**
     * 检查对象中对应属性是否重复
     * @param queryWrapper 查询条件器
     * @param t 对象
     * @param column 属性, 下划线形式
     */
    default T checkIsRepeat(QueryWrapper<T> queryWrapper, T t, String column, String message) {
        queryWrapper.eq(column, ReflexUtil.getValueByName(t, HumpUtil.lineToHump(column)));
        List<T> list = this.list(queryWrapper);
        if (CollectionUtil.isNotEmpty(list)) {
            throw new BusinessException(StringUtils.isNotBlank(message) ? message : Constants.INSERT_VALUE_REPEAT);
        }
        return t;
    }

    /**
     * 根据第一个参数是否为空决定返回是否查询成功
     * @param t 判断的对象 一般是查询出来的对象
     * @param object 其他
     * @return
     */
    default JsonResult returnObject(T t, Object object) {
        if (ObjectUtil.isEmpty(t)) {
            return JsonResult.selectNotFound(object, null);
        }
        return JsonResult.selectSuccess(t, object);
    }

    /**
     * 根据第一个集合是否为空或者长度是否为0决定返回是否查询成功
     * @param tList 判断的对象 一般是查询出来的对象
     * @param object 其他
     * @return
     */
    default JsonResult returnObject(List<T> tList, Object object) {
        if (CollectionUtil.isEmpty(tList)) {
            return JsonResult.selectNotFound(object, null);
        }
        return JsonResult.selectSuccess(tList, object);
    }

    /**
     *
     * 检查对象中对应属性是否为空和是否重复.
     * @param id 更新操作时重复判断 过滤自身数据
     * @param queryWrapper 查询条件器
     * @param t 对象
     * @param column 属性, 下划线形式
     * @param repeatMessage 重复的提示信息
     * @param nullMessage 空置的提示信息
     */
    default void checkIsEmptyAndRepeat(String id, QueryWrapper<T> queryWrapper, T t, String column, String repeatMessage, String nullMessage) {
//        Object valueByName = ReflexUtil.getValueByName(t, HumpUtil.lineToHump(column));
//        AssertUtil.hasText(valueByName + "", nullMessage);
//        queryWrapper.eq(column, valueByName).eq(Constants.DEL_FLAG, BaseDomain.DEL_FLAG_NORMAL)
//                .eq("create_id", ThreadLocalUtil.getUserId()).ne(StringUtils.isNotEmpty(id), "id", id);
//        List<T> list = this.list(queryWrapper);
//        if (CollectionUtil.isNotEmpty(list)) {
//            throw new BusinessException(Constants.INSERT_VALUE_REPEAT, repeatMessage);
//        }
        this.checkIsEmptyAndRepeat(id, queryWrapper, t, column, repeatMessage, nullMessage, null, null);
    }

    /**
     * 检查对象中对应属性是否为空和是否重复.
     * @param id 更新操作时重复判断 过滤自身数据
     * @param queryWrapper 查询条件器
     * @param t 对象 必须是包含属性的对象，继承属性不行
     * @param column 属性, 下划线形式
     * @param repeatMessage 重复的提示信息
     * @param nullMessage 空置的提示信息
     * @param anotherColumn 查询时的其他条件
     * @param anotherValue 查询时的其他条件
     */
    default void checkIsEmptyAndRepeat(String id, QueryWrapper<T> queryWrapper, T t, String column, String repeatMessage, String nullMessage, String anotherColumn, String anotherValue) {
        Object valueByName = ReflexUtil.getValueByName(t, HumpUtil.lineToHump(column));
        AssertUtil.hasText(valueByName + "", nullMessage);
        queryWrapper.eq(column, valueByName).eq(Constants.DEL_FLAG, BaseDomain.DEL_FLAG_NORMAL)
                .eq("create_id", ThreadLocalUtil.getUserId()).ne(StringUtils.isNotEmpty(id), "id", id)
                .eq(StringUtils.isNotEmpty(anotherColumn) && StringUtils.isNotBlank(anotherValue), anotherColumn, anotherValue);
        List<T> list = this.list(queryWrapper);
        if (CollectionUtil.isNotEmpty(list)) {
            throw new BusinessException(StringUtils.isNotBlank(repeatMessage) ? repeatMessage : Constants.INSERT_VALUE_REPEAT);
        }
    }

    /**
     *
     * 检查对象中对应属性是否重复.
     * @param id 更新操作时重复判断 过滤自身数据 update时该参数为自身id，反之为空即可
     * @param queryWrapper 查询条件器
     * @param t 对象
     * @param column 属性, 下划线形式
     * @param repeatMessage 重复的提示信息
     */
    default void checkIsRepeat(String id, QueryWrapper<T> queryWrapper, T t, String column, String repeatMessage, String anotherColumn, String anotherValue) {
        Object valueByName = ReflexUtil.getValueByName(t, HumpUtil.lineToHump(column));
        queryWrapper.eq(column, valueByName).eq(Constants.DEL_FLAG, BaseDomain.DEL_FLAG_NORMAL)
                .eq("create_id", ThreadLocalUtil.getUserId())
                .ne(StringUtils.isNotEmpty(id), "id", id)
                .eq(StringUtils.isNotEmpty(anotherColumn) && StringUtils.isNotBlank(anotherValue), anotherColumn, anotherValue);
        List<T> list = this.list(queryWrapper);
        if (CollectionUtil.isNotEmpty(list)) {
            throw new BusinessException(Constants.INSERT_VALUE_REPEAT);
        }
    }

    /**
     * 检查对象中对应属性是否为空
     * @param t 对象
     * @param columns 属性, 驼峰式
     */
    default void checkColumnIsEmpty(T t, String... columns) throws NoSuchFieldException, IllegalAccessException {
        if (ObjectUtil.isEmpty(columns) || columns.length == 0) {
            throw new BusinessException(REFLECT_CHECK_EMPTY_COLUMN_ARRAY_EMPTY);
        }
        for (String column : columns) {
            if (StringUtils.isBlank(column)) {
                continue;
            }
            Class<?> aClass = t.getClass();
            Field declaredField = aClass.getDeclaredField(column);
            declaredField.setAccessible(true);
            AssertUtil.hasText(declaredField.get(t), declaredField.getName() + "不能为空");
        }
    }

    default <T extends BaseDomain> void updateMoney(String column, String id, IService<T> service, String userId) {
        if (StringUtils.isBlank(id)) {
            return;
        }
        QueryWrapper<T> eq = new BaseWrapper<T>().init(userId).eq(column, id);
        List<T> list = service.list(eq);

    }


}
